package com.ptswitch.material.util.security;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.hxzon.tapestry5.model.ValueGroup;
import org.hxzon.tapestry5.model.ValueGroupImpl;
import org.hxzon.tapestry5.model.ValueGrouper;

import com.ptswitch.material.model.security.Permission;
import com.ptswitch.material.model.security.Role;

public class RoleUtil {

    public static final List<Role> roles = new ArrayList<Role>();
    public static final String RoleGroupName_System = "system";
    public static final String RoleGroupName_Relate = "relate";
    public static final String RoleGroupName_Department = "department";
    public static final String RoleGroupName_Custom = "custom";
    //
    public static final Role Admin = new Role("admin", "超级管理员", RoleGroupName_System);
    //
    public static final Role MaterialCreater = new Role("materialCreater", "物料创建者", RoleGroupName_Relate);
    //
    public static final Role ContractCreater = new Role("contractCreater", "合同创建者", RoleGroupName_Relate);
    public static final Role ContractFinancial = new Role("contractFinancial", "合同财务接口人", RoleGroupName_Relate);
    public static final Role ContractProduction = new Role("contractProduction", "合同生产接口人", RoleGroupName_Relate);
    public static final Role ContractAuditor = new Role("contractAuditor", "采购审核接口人", RoleGroupName_Relate);
    //
    public static final Role DepartmentBuyer = new Role("departmentBuyer", "采购部", RoleGroupName_Department);
    public static final Role DepartmentFinancial = new Role("departmentFinancial", "财务部", RoleGroupName_Department);
    public static final Role DepartmentProduction = new Role("departmentProduction", "生产部", RoleGroupName_Department);
    public static final Role DepartmentHardware = new Role("departmentHardware", "硬件部", RoleGroupName_Department);
    public static final Role DepartmentSoftware = new Role("departmentSoftware", "软件部", RoleGroupName_Department);

    public static final void init() {
        initRole(Admin, PermissionUtil.All);
        initRole(MaterialCreater, PermissionUtil.MaterialAll);
        //
        initRole(ContractCreater, PermissionUtil.ContractItemAdd, PermissionUtil.ContractItemDelete,//
                PermissionUtil.ContractItemEdit, PermissionUtil.ContractItemReceive, PermissionUtil.ContractItemReturn,//
                PermissionUtil.ContractAskDelete, PermissionUtil.ContractAskOk, PermissionUtil.ContractAskReset,//
                PermissionUtil.ContractPaymentAsk, PermissionUtil.ContractRefundAsk, PermissionUtil.ContractInvoiceAsk,//
                PermissionUtil.ContractAttachment, PermissionUtil.ContractSendEmail);
        initRole(ContractFinancial, //
                PermissionUtil.ContractPaymentReply, PermissionUtil.ContractRefundReply, PermissionUtil.ContractInvoiceReply);
        initRole(ContractProduction, PermissionUtil.ContractItemExamine);
        initRole(ContractAuditor, //
                PermissionUtil.ContractDelete, PermissionUtil.ContractReset);
        appendCommonContractPermissions(ContractCreater);
        appendCommonContractPermissions(ContractFinancial);
        appendCommonContractPermissions(ContractProduction);
        appendCommonContractPermissions(ContractAuditor);
        //
        initRole(DepartmentBuyer, PermissionUtil.ContractCreate, PermissionUtil.ContractList, PermissionUtil.ContractSearch);
        //
        Field[] fields = RoleUtil.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.getType() == Role.class) {
                try {
                    Object o = field.get(new PermissionUtil());
                    if (o instanceof Role) {
                        roles.add((Role) o);
                    }
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                }
            }
        }
    }

    private static void initRole(Role role, Permission... permissions) {
        if (role.getPermissions() == null) {
            role.setPermissions(new ArrayList<Permission>());
        }
        role.getPermissions().addAll(Arrays.asList(permissions));
    }

    private static void appendCommonContractPermissions(Role role) {
        role.getPermissions().add(PermissionUtil.ContractList);
        role.getPermissions().add(PermissionUtil.ContractSearch);
        role.getPermissions().add(PermissionUtil.ContractView);
        role.getPermissions().add(PermissionUtil.ContractAttachmentUpload);
    }

    static {
        init();
    }

    //-----------------
    private static class RoleValueGroup extends ValueGroupImpl<Role> implements ValueGroup<Role> {
        private String _roleGroupName;

        public RoleValueGroup(String displaypName, String roleGroupName) {
            super(displaypName);
            _roleGroupName = roleGroupName;
        }

        public String getRoleGroupName() {
            return _roleGroupName;
        }
    }

    //---------------
    private static final RoleValueGroup roleGroup_Relate = new RoleValueGroup("动态角色", RoleGroupName_Relate);
    private static final RoleValueGroup roleGroup_System = new RoleValueGroup("系统角色", RoleGroupName_System);
    private static final RoleValueGroup roleGroup_Department = new RoleValueGroup("部门角色", RoleGroupName_Department);
    private static final RoleValueGroup roleGroup_Custom = new RoleValueGroup("自定义角色", RoleGroupName_Custom);
    public static final ValueGrouper<Role> roleValueGrouper = new ValueGrouper<Role>() {
        public List<ValueGroup<Role>> groups(List<Role> roles) {
            List<ValueGroup<Role>> vgs = new ArrayList<ValueGroup<Role>>();
            vgs.add(roleGroup_Relate);//add for EditPermission page
            vgs.add(roleGroup_System);
            vgs.add(roleGroup_Department);
            vgs.add(roleGroup_Custom);
            for (ValueGroup<Role> vg : vgs) {
                ((RoleValueGroup) vg).clearValues();
            }
            for (Role role : roles) {
                for (ValueGroup<Role> vg : vgs) {
                    RoleValueGroup rvg = (RoleValueGroup) vg;
                    if (rvg.getRoleGroupName().equals(role.getRoleGroup())) {
                        rvg.addValue(role);
                    }
                }
            }
            return vgs;
        }
    };
}
